#include <SDL2/SDL.h>
#undef  main
#include <iostream>

using namespace std;

constexpr int WindowWidth = 800;
constexpr int WindowHeight = 600;

#ifdef START_ID
#define GEN_ID() (IDType)((START_ID)+(__LINE__))
#else
#define GEN_ID() (IDType)(__LINE__)
#endif

typedef unsigned int IDType;

enum EventType {
    EVENT_NOTHING,
    EVENT_CLICK
};

enum {
    ID_UNKONOW = 0,
    ID_ANY,
    ID_BUTTON1,
    ID_SLIDBAR1
};

struct UIState {
    SDL_Point mouse_position;
    bool mouse_down;

    IDType hot_item;
    IDType active_item;
    IDType kbd_item;
    SDL_Keycode key;
} uistate = {{0, 0}, false, 0, 0, 0, SDLK_UNKNOWN};

EventType Button(SDL_Renderer* render, IDType id, int x, int y, int w, int h, SDL_Color, SDL_Color);
EventType SlidBar(SDL_Renderer* render, IDType id, int x, int y, int len, int min, int max, int& value);

void imgui_prepare();
void imgui_finish();

int value = 20;

int main(int argc, char** argv) {
    SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTS);
    SDL_Window* window = SDL_CreateWindow("sdl imgui",
                                          SDL_WINDOWPOS_CENTERED,
                                          SDL_WINDOWPOS_CENTERED,
                                          WindowWidth, WindowHeight,
                                          SDL_WINDOW_SHOWN);
    SDL_Renderer* render = SDL_CreateRenderer(window, -1, 0);
    bool is_quit = false;
    SDL_Event event;

    while (!is_quit) {
        SDL_SetRenderDrawColor(render, 200, 200, 200, 255);
        SDL_RenderClear(render);
        imgui_prepare();
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_MOUSEMOTION) {
                uistate.mouse_position.x = event.motion.x;
                uistate.mouse_position.y = event.motion.y;
            }
            if (event.type == SDL_MOUSEBUTTONDOWN) {
                if (event.button.button == SDL_BUTTON_LEFT) {
                    uistate.mouse_down = true;
                }
            }
            if (event.type == SDL_MOUSEBUTTONUP) {
                if (event.button.button == SDL_BUTTON_LEFT) {
                    uistate.mouse_down = false;
                }
            }
            if (event.type == SDL_KEYDOWN) {
                uistate.key = event.key.keysym.sym;
            }
            if (event.type == SDL_KEYUP) {
                uistate.key = SDLK_UNKNOWN;
            }
            if (event.type == SDL_QUIT)
                is_quit = true;
        }
        EventType event = Button(render, ID_BUTTON1, 100, 100, 64, 40, {200, 0, 0, 255}, {0, 200, 0, 255});
        if (event == EVENT_CLICK) {
            cout << "button clicked" << endl;
        }
        SlidBar(render, ID_SLIDBAR1, 100, 300, 300, 0, 100, value);
        cout << "slid " << value << endl;
        SDL_RenderPresent(render);
        imgui_finish();
        SDL_Delay(30);
    }

    SDL_Quit();
    return 0;
}

EventType Button(SDL_Renderer* render, IDType id, int x, int y, int w, int h, SDL_Color color, SDL_Color press_color) {
    SDL_Rect rect = {x, y, w, h};
    SDL_SetRenderDrawColor(render, color.r, color.g, color.b, 255);
    if (SDL_PointInRect(&uistate.mouse_position, &rect)) {
        uistate.hot_item = id;
        if (uistate.active_item == 0 && uistate.mouse_down) {
            uistate.active_item = id;
        }
    }
    if (uistate.active_item == id)
        SDL_SetRenderDrawColor(render, press_color.r, press_color.g, press_color.b, 255);
    SDL_RenderFillRect(render, &rect);
    if (uistate.active_item == id)
        return EVENT_CLICK;
    return EVENT_NOTHING;
}

EventType SlidBar(SDL_Renderer* render, IDType id, int x, int y, int len, int min, int max, int& value) {
    const int h = 20;
    const int button_len = 16;
    const int move_step = 1;
    int draw_len = len - button_len;
    SDL_Rect rect = {x, y, len, h};
    if (SDL_PointInRect(&uistate.mouse_position, &rect)) {
        uistate.hot_item = id;
        if (uistate.active_item == 0 && uistate.mouse_down) {
            uistate.active_item = id;
            uistate.kbd_item = id;
        }
    }
    if (uistate.active_item == id) {
        value = (uistate.mouse_position.x - x)/(float)(draw_len)*(max-min)+min;
    }
    if (uistate.kbd_item == id) {
        if (uistate.key == SDLK_LEFT)
            value -= move_step;
        if (uistate.key == SDLK_RIGHT)
            value += move_step;
    }
    if (value < min)
        value = min;
    if (value > max)
        value = max;

    SDL_Color bg_color = {100, 100, 100, 255};
    SDL_Color button_color = {50, 50, 50, 255};
    SDL_Color board_color = {0, 0, 0, 255};
    SDL_SetRenderDrawColor(render, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
    SDL_RenderFillRect(render, &rect);
    SDL_SetRenderDrawColor(render, board_color.r, board_color.g, board_color.b, board_color.a);
    SDL_RenderDrawRect(render, &rect);

    int pos_x = x+(value-min)/(float)(max-min)*draw_len;
    SDL_Rect button_rect = {pos_x, y+2, button_len, button_len};
    SDL_SetRenderDrawColor(render, button_color.r, button_color.g, button_color.b, button_color.a);
    SDL_RenderFillRect(render, &button_rect);

    return EVENT_NOTHING;
}

void imgui_prepare() {
    uistate.hot_item = 0;
}

void imgui_finish() {
    if (!uistate.mouse_down) {
        uistate.active_item = 0;
    }
}

